/*
 * > /*
>  * INSANE - Interactive Structural Analysis Environment
>  *
>  * Copyright (C) 2003-2004
>  * Universidade Federal de Minas Gerais
>  * Escola de Engenharia
>  * Departamento de Engenharia de Estruturas
>  *
>  * Author's email :     insane@dees.ufmg.br
>  * Author's Website :   http://www.dees.ufmg.br/insane
>  *
>  * This program is free software; you can redistribute it and/or
>  * modify it under the terms of the GNU General Public License
>  * as published by the Free Software Foundation; either version 2
>  * of the License, or any later version.
>  *
>  * This program is distributed in the hope that it will be useful,
>  * but WITHOUT ANY WARRANTY; without even the implied warranty of
>  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>  * GNU General Public License for more details.
>  *
>  * You should have received a copy of the GNU General Public License
>  * along with this program; if not, write to the Free Software
>  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-
> 1307, USA.
 *
 */

package br.ufmg.dees.insane.ui.rich.prep.view.command;

import java.awt.Toolkit;
import java.util.ArrayList;

import javax.swing.JOptionPane;

import br.ufmg.dees.insane.commons.command.Command;
import br.ufmg.dees.insane.model.geo.halfEdgeDataStructure.Edge;
import br.ufmg.dees.insane.model.geo.halfEdgeDataStructure.Vertex;
import br.ufmg.dees.insane.model.prep.GeoPrepModel;
import br.ufmg.dees.insane.model.prep.HalfEdgePrepModel;
import br.ufmg.dees.insane.ui.rich.prep.controller.PrepControllerHE;
import br.ufmg.dees.insane.ui.rich.prep.view.DesktopPrep;
import br.ufmg.dees.insane.ui.rich.prep.view.InterfacePrep;
import br.ufmg.dees.insane.ui.rich.prep.view.TextAreaPanel;

/**
 *
 * @author Ferreira, Reginaldo & Pitangueira, Roque
 * @since 05/03/2007
 */
public class MergeFramesCommand implements Command, Cloneable {
	
    private InterfacePrep intFrame;
    private DesktopPrep desktop;
    private PrepControllerHE controller;
    private ArrayList selected = new ArrayList();
    private TextAreaPanel DesktopTextArea;
    private HalfEdgePrepModel modelHE;
    private Edge edge1, edge2, newEdge;
    
//  ****************************************************************************
	
    /** This command break a frame at a especified node. */
    public MergeFramesCommand() {}  
    
//  ****************************************************************************
	
    /** The execute method. */
    public void execute()
    {
    	String msg = "";
    	
        this.controller = (PrepControllerHE)this.intFrame.getView().getController();
        this.modelHE = ((GeoPrepModel)this.intFrame.getModel()).getDataStructure();
        this.selected = controller.getSelection();
        this.DesktopTextArea = this.desktop.getDesktopTextArea();
        
    	if ((!selected.isEmpty()) && (selected.size() == 2))
    	{	    	
    		if ( ((Object)selected.get(0) instanceof Edge) &&
    		     ((Object)selected.get(1) instanceof Edge))
    		{
    			edge1 = (Edge)selected.get(0);
    			edge2 = (Edge)selected.get(1);
    			this.mergeFrames();
    			msg = "The frames was merged .";
    			DesktopTextArea.addText(msg);
    		}
    		else
    		{
    			Toolkit.getDefaultToolkit().beep();
        		msg = "One of the elements is not a frame.";
        		desktop.getDesktopTextArea().addText(msg);	
    			JOptionPane.showMessageDialog(desktop, msg,
    					"Alert Message", JOptionPane.INFORMATION_MESSAGE);
    		}
    	}
    	else
    	{
    		Toolkit.getDefaultToolkit().beep();
    		msg = "It's necessary to select only two frames.";
    		desktop.getDesktopTextArea().addText(msg);
			JOptionPane.showMessageDialog(desktop, msg,
					"Alert Message", JOptionPane.INFORMATION_MESSAGE);
    	}
    	// limpa as listas
		selected.clear();
		controller.compose();
		controller.getModel().update();
		desktop.addToUndo((Command)this.clone());
    }   
    
//  ****************************************************************************
    
    private void mergeFrames()
    {
    	Vertex e1Vi, e1Vf, e2Vi, e2Vf;
    	String msg = "";

      	e1Vi = edge1.getVStart();
    	e1Vf = edge1.getVEnd();
    	
      	e2Vi = edge2.getVStart();
    	e2Vf = edge2.getVEnd();
    	
    	OpEulerMEV op = new OpEulerMEV(modelHE);
    	
    	if ( e1Vi.equals(e2Vi) )
    	{
    		newEdge = op.makeEdge(e1Vf, e2Vf);
    	}
    	else if ( e1Vf.equals(e2Vi))
    	{
    		newEdge = op.makeEdge(e1Vi, e2Vf);
    	}
    	else if ( e1Vi.equals(e2Vf))
    	{
    		newEdge = op.makeEdge(e1Vf, e2Vi);
    	}
    	else if ( e1Vf.equals(e2Vf))
    	{
    		newEdge = op.makeEdge(e1Vi, e2Vi);
    	}
    	else
    	{
    		Toolkit.getDefaultToolkit().beep();
    		msg = "It's not possible to merge the selected edges.";
    		desktop.getDesktopTextArea().addText(msg);
			JOptionPane.showMessageDialog(desktop, msg,
					"Alert Message", JOptionPane.INFORMATION_MESSAGE);
    	}
		controller.add(newEdge);
		controller.remove(edge1);
		controller.remove(edge2);
    }
        
//  ****************************************************************************
	
    /** Remake the old edge. */
    public void undo()
    {
    	String msg = "";
		controller.remove(newEdge);
		controller.add(edge1);
		controller.add(edge2);
		controller.compose();
		controller.getModel().update();
		msg = "[Undo] The frames was separated again. ";
		DesktopTextArea.addText(msg);
    }
	
//  ****************************************************************************
	
    /** Impossible to redo - not implemented yet */
    public void redo()
    {
    	
    }
    
//  ****************************************************************************    
    
    /** Clone this command. */
	public Object clone() {
        try {
        	MergeFramesCommand cmd = (MergeFramesCommand)super.clone();
            return cmd;
        } catch (CloneNotSupportedException e) {
            throw new Error("Clonning ERROR - This should never happen!");
        }
    }     
    
    
//	****************************************************************************
	
    /** Sets the desktop and the current internalFrame */
	public void setParent(InterfacePrep currentIntFrame, DesktopPrep dsk)
	{
		this.intFrame = currentIntFrame;
		this.desktop = (DesktopPrep)dsk;
	}    
	
//	****************************************************************************  
}
